/////////////////////////////////////////////////////////////////////////////
// This file is part of the "Java-DAP" project, a Java implementation
// of the OPeNDAP Data Access Protocol.
//
// Copyright (c) 2007 OPeNDAP, Inc.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
/////////////////////////////////////////////////////////////////////////////
using System;
using ExprParserConstants = NDODS.DAP.Parser.ExprParserConstants;
// used only for toString()
namespace NDODS.DAP.Server
{
	
	/// <summary> Represents a clause which compares subclauses, using one of the
	/// relative operators supported by the Operator class.
	/// 
	/// </summary>
	/// <author>  joew
	/// </author>
	/// <seealso cref="Operator">
	/// </seealso>
	/// <seealso cref="ClauseFactory">
	/// </seealso>
	public class RelOpClause:AbstractClause, ITopLevelClause
	{
		virtual public bool Value
		{
			get
			{
				return value_Renamed;
			}
			
		}
		/// <summary> Returns a SubClause representing the right-hand side of the
		/// comparison.
		/// </summary>
		virtual public ISubClause LHS
		{
			get
			{
				return lhs;
			}
			
		}
		/// <summary> Returns a list of SubClauses representing the right-hand side of the
		/// comparison.
		/// </summary>
		virtual public System.Collections.IList RHS
		{
			get
			{
				return rhs;
			}
			
		}
		/// <summary> Returns the type of comparison
		/// 
		/// </summary>
		/// <seealso cref="NDODS.DAP.Parser.ExprParserConstants">
		/// </seealso>
		virtual public int Operator
		{
			get
			{
				return operator_Renamed;
			}
			
		}
		/// <summary> Creates a new RelOpClause. If the lhs and all the elements of the rhs
		/// are constant, the RelOpClause will be flagged as constant, and
		/// evaluated immediately.
		/// 
		/// </summary>
		/// <param name="operator">The operator invoked by the clause
		/// </param>
		/// <param name="lhs">     The left-hand side of the comparison.
		/// </param>
		/// <param name="rhs">     A list of SubClauses representing the right-hand side of the
		/// comparison.
		/// </param>
		/// <throws>  DAP2ServerSideException Thrown if the clause is constant, but </throws>
		/// <summary>                        the attempt to Evaluate it fails.
		/// </summary>
		protected internal RelOpClause(int operator_Renamed, ISubClause lhs, System.Collections.IList rhs)
		{
			
			this.operator_Renamed = operator_Renamed;
			this.lhs = lhs;
			this.rhs = rhs;
			this.children = new System.Collections.ArrayList();
			children.Add(lhs);
			SupportClass.ICollectionSupport.AddAll(children, rhs);
			this.constant = true;
			System.Collections.IEnumerator it = children.GetEnumerator();
			//UPGRADE_TODO: Method 'java.util.Iterator.hasNext' was converted to 'System.Collections.IEnumerator.MoveNext' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilIteratorhasNext'"
			while (it.MoveNext())
			{
				//UPGRADE_TODO: Method 'java.util.Iterator.next' was converted to 'System.Collections.IEnumerator.Current' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilIteratornext'"
				ISubClause current = (ISubClause) it.Current;
				current.Parent = this;
				if (!current.Constant)
				{
					constant = false;
				}
			}
			if (constant)
			{
				Evaluate();
			}
		}
		
		public virtual bool Evaluate()
		{
			
			if (constant && defined)
			{
				return value_Renamed;
			}
			
			if (rhs.Count == 1)
			{
                value_Renamed = NDODS.DAP.Server.Operator.op(operator_Renamed, lhs.Evaluate(), ((ISubClause)rhs[0]).Evaluate());
			}
			else
			{
				value_Renamed = false;
				System.Collections.IEnumerator it = rhs.GetEnumerator();
				//UPGRADE_TODO: Method 'java.util.Iterator.hasNext' was converted to 'System.Collections.IEnumerator.MoveNext' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilIteratorhasNext'"
				while (it.MoveNext() && !value_Renamed)
				{
					//UPGRADE_TODO: Method 'java.util.Iterator.next' was converted to 'System.Collections.IEnumerator.Current' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilIteratornext'"
                    if (NDODS.DAP.Server.Operator.op(operator_Renamed, lhs.Evaluate(), ((ISubClause)it.Current).Evaluate()))
					{
						value_Renamed = true;
					}
				}
			}
			defined = true;
			return value_Renamed;
		}
		
		/// <summary> Prints the original string representation of this clause.
		/// For use in debugging.
		/// </summary>
		public override System.String ToString()
		{
			System.Text.StringBuilder buf = new System.Text.StringBuilder();
			//UPGRADE_TODO: The equivalent in .NET for method 'java.lang.Object.toString' may return a different value. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1043'"
			buf.Append(lhs.ToString());
			
			System.String op = NDODS.DAP.Parser.ExprParserConstants_Fields.tokenImage[operator_Renamed];
			op = op.Substring(1, (op.Length - 1) - (1));
			buf.Append(op);
			//buf.append(ExprParserConstants.tokenImage[operator].substring(2, 3));
			
			if (rhs.Count == 1)
			{
				//UPGRADE_TODO: The equivalent in .NET for method 'java.lang.Object.toString' may return a different value. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1043'"
				buf.Append(rhs[0].ToString());
			}
			else
			{
				buf.Append("{");
				System.Collections.IEnumerator it = rhs.GetEnumerator();
				//UPGRADE_TODO: Method 'java.util.Iterator.next' was converted to 'System.Collections.IEnumerator.Current' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilIteratornext'"
				buf.Append(it.Current);
				//UPGRADE_TODO: Method 'java.util.Iterator.hasNext' was converted to 'System.Collections.IEnumerator.MoveNext' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilIteratorhasNext'"
				while (it.MoveNext())
				{
					buf.Append(",");
					//UPGRADE_TODO: The equivalent in .NET for method 'java.lang.Object.toString' may return a different value. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1043'"
					//UPGRADE_TODO: Method 'java.util.Iterator.next' was converted to 'System.Collections.IEnumerator.Current' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilIteratornext'"
					buf.Append(it.Current.ToString());
				}
				buf.Append("}");
			}
			return buf.ToString();
		}
		
		protected internal bool value_Renamed;
		
		protected internal int operator_Renamed;
		
		protected internal ISubClause lhs;
		
		protected internal System.Collections.IList rhs;
	}
}